#include "worker.h"
#include "../server_handler/handler.h"
#include "../log/log.h"
#include "../dir/clientSession.h"

void *worker_task(void *arg)
{
    // 先获取共享资源
    shared_resource_t *shared_resource = (shared_resource_t *)arg;
    // 用户会话指针
    clientSession_t *user_session;
    while (1)
    {
        // 加锁
        pthread_mutex_lock(&shared_resource->mutex);
        // 如果任务队列为空且没有退出标志，等待新任务到来
        // 注意这里用while而不是if，防止虚假唤醒
        while (shared_resource->task_queue.size == 0 && shared_resource->exit_flag == 0)
        {
            pthread_cond_wait(&shared_resource->cond, &shared_resource->mutex);
        }
        // 如果有退出标志，解锁并退出线程
        if (shared_resource->exit_flag == 1)
        {
            pthread_mutex_unlock(&shared_resource->mutex);
            break;
        }
        // 从任务队列中取出一个任务
        user_session = shared_resource->task_queue.front->session;
        task_queue_dequeue(&shared_resource->task_queue);
        // 解锁
        pthread_mutex_unlock(&shared_resource->mutex);
        // 调用handler处理任务
        // 登录校验
        int ret = handle_login(user_session);
        if (ret < 0)
        {
            // TODO:封装
            close(user_session->netfd);
            // 释放用户会话
            // TODO:释放栈
            free(user_session);
            // 出错，记录日志
            LOG_ERROR("error occurred while handling login for netfd=%d", user_session->netfd);
        }
        if (ret == 1)
        {
            // 用户正常断连，记录日志
            close(user_session->netfd);
            // 释放用户会话
            // TODO:释放栈
            free(user_session);
            LOG_INFO("client disconnected normally when handling login, netfd=%d", user_session->netfd);
        }
        user_session->is_login = 1; // 标记用户已登录
        // 处理用户命令
        ret = handle_command(user_session);
        // 错误处理
        if (ret < 0)
        {
            // 任务处理完成，关闭用户连接
            close(user_session->netfd);
            // 释放用户会话
            // TODO:释放栈
            free(user_session);
            // 出错，记录日志
            LOG_ERROR("error occurred while handling command for netfd=%d", user_session->netfd);
        }
        if (ret == 1)
        {
            // 任务处理完成，关闭用户连接
            close(user_session->netfd);
            // 释放用户会话
            // TODO:释放栈
            free(user_session);
            // 用户正常断连，记录日志
            LOG_INFO("client disconnected normally when handing command, netfd=%d", user_session->netfd);
        }
    }

    // 线程退出
    pthread_exit(NULL);
}

void workerList_init(worker_list_t *list, int worker_count, shared_resource_t *shared_resource)
{
    // 参数检查
    if (list == NULL || worker_count <= 0)
    {
        return;
    }

    // 初始化工作线程列表
    bzero(list, sizeof(worker_list_t));
    list->worker_count = worker_count;
    list->workers = (pthread_t *)malloc(sizeof(pthread_t) * worker_count);
    // TODO: 错误检查
    if (list->workers == NULL)
    {
        // 记录错误日志
        LOG_ERROR("workerList_init: malloc failed");
        exit(-1);
    }
    // 创建工作线程
    for (int i = 0; i < worker_count; i++)
    {
        pthread_create(&list->workers[i], NULL, worker_task, shared_resource);
    }

    return;
}